import {formatDate} from './func';

// 测试耗时
export const testCost = async (tag: string, exeFn: () => Promise<boolean>) => {
  const startTime = new Date().getTime();
  console.log(`[testCost ${tag}]`, 'start');
  console.log(`[testCost ${tag}]`, 'middle', `cost ${new Date().getTime() - startTime}ms`)
  await exeFn();
  console.log(`[testCost ${tag}]`, 'end', `cost ${new Date().getTime() - startTime}ms`)
}

export class TestUtil {
  private startTime: number = 0;

  constructor(startTime?: number) {
    this.startTime = startTime ?? new Date().getTime()
  }

  start(tag?: string) {
    this.startTime = new Date().getTime();
    if (tag) console.log(`[TestUtil ${tag}]`, 'start')
    return this;
  }

  end(tag?: string) {
    console.log(`[TestUtil ${tag}]`, 'end', `cost ${new Date().getTime() - this.startTime}ms`)
    return this;
  }
}

export interface RecordData {
  methodName: string;
  date: number;
  tag?: string;
}

interface RecordDataCount extends RecordData { count: number }

class RecordUtil {
  private recordList: RecordData[] = [];

  // 用于记录埋点 注意函数的this指向
  record(tag?: string, warnOnce?: number) {
    const that = this;
    return function (_: any, methodName: any, desc: any) {
      const oldValue = desc.value
      desc.value = function (...args) {
        tag && console.log('[RecordUtil]', tag);
        console.log('[RecordUtil]', `${methodName} 方法被调用`);
        console.log('[RecordUtil]', '方法描述:', JSON.stringify(desc));
        that.recordList.push({
          date: new Date().getTime(),
          methodName,
          tag
        })
        if (warnOnce) {
          const result:RecordDataCount[] = [];
          let currentItem:RecordData = null;
          let currentCount = 0;
          that.recordList.reduce((acc: RecordDataCount, item, index) => {
            if (item.methodName === currentItem?.methodName) {
              currentCount++;
            } else {
              if (currentItem !== null) {
                result.push({ ...currentItem, count: currentCount });
              }
              currentItem = item;
              currentCount = 1;
            }
            if (index === that.recordList.length - 1) {
              result.push({...currentItem, count: currentCount });
            }
            return acc;
          });
          console.log(JSON.stringify(result))
          const {count} = result.filter(item=>item.methodName === methodName).reduce((pre,cur)=>cur.count>(pre?.count||0)?cur:pre)
          count >= warnOnce && console.warn('[RecordUtil]', `${methodName} 方法被连续调用了 ${count} 次`)
        }
        return oldValue.apply(this, args);
      };
      return desc;
    }
  }

  getAllRecord(isFormatStr?: boolean) {
    return isFormatStr ?
    this.recordList?.map(({ methodName, tag,date}) => `[${formatDate(new Date(date))}] ${methodName} ${tag}`) :
    this.recordList
  }
}

export const RecUtil = new RecordUtil()
